package com.hefei.garden.config.netty.server;

import com.hefei.garden.config.netty.pojo.NettyBaseInfo;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author: yxchen6
 * @date: 2022/7/24 14:46
 * @description:
 */
@Service
public class NettyServer implements Runnable {

    private static final Logger LOGGER = LoggerFactory.getLogger(NettyServer.class);

    // 服务操作同步锁
    private static final Object object = new Object();

    @Autowired
    NettyServerInitializer nettyServerInitializer;
    @Autowired
    NettyBaseInfo nettyBaseInfo;
    private Channel channel;
    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    // true 说服务已经启动
    private volatile boolean serverStatus;

    private NettyServer() {
    }

    /**
     * netty服务端启动
     */
    public void initNettyServer() {
        if (serverStatus) {
            return;
        }
        synchronized (object) {
            if (serverStatus) {
                return;
            }
            serverStatus = true;
        }
        Thread nettyServer = new Thread(this);
        nettyServer.start();
        LOGGER.info("netty服务开始启动...");
    }

    /**
     * netty服务端关闭
     */
    public void destroyNettyServer() {
        if (!serverStatus) {
            return;
        }
        synchronized (object) {
            if (!serverStatus) {
                return;
            }
            serverStatus = false;
        }
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
        channel.closeFuture().syncUninterruptibly();
        bossGroup = null;
        workerGroup = null;
        channel = null;
        LOGGER.info("netty服务关闭完成...");
    }

    @Override
    public void run() {
        bossGroup = new NioEventLoopGroup(nettyBaseInfo.getBossThread());
        workerGroup = new NioEventLoopGroup(nettyBaseInfo.getWorkerThread());
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup);
            bootstrap.channel(NioServerSocketChannel.class);
            // 相关解码器设置
            bootstrap.childHandler(nettyServerInitializer);
            // 服务器绑定端口监听
            ChannelFuture channelFuture = bootstrap.bind(nettyBaseInfo.getPort()).sync();
            LOGGER.info("netty服务启动完毕...");
            // 监听服务器关闭监听
            channelFuture.channel().closeFuture().sync();
            channel = channelFuture.channel();
        } catch (InterruptedException e) {
            e.printStackTrace();
            LOGGER.error("netty服务启动异常...");
        } finally {
            serverStatus = false;
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}


